--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_sekibanki = General:new(extension, "hy_sekibanki", "jin_k", 4, 4, General.Female)
    local head_dance = fk.CreateSkill {
        name = "head_dance",
        tags = {
            Skill.Genetics
        },
        dynamic_desc = function(self, player, lang)
            if player:getMark("head_dance_mutation") ~= 0 then
                return "head_dance_mutation"
            end
            return "head_dance"
        end
    }
    head_dance:addEffect("active", {
        can_use = function(self, player)
            return player:usedEffectTimes(self.name, Player.HistoryPhase) < 1 and not player:isKongcheng()
        end,
        card_filter = Util.FalseFunc,
        target_num = 1,
        target_filter = function(self, player, to_select, selected, selected_cards)
            return #selected == 0 and to_select ~= player
        end,
        prompt = function(self, player, selected_cards, selected_targets)
            return "head_dance_prompt"
        end,
        on_use = function(self, room, skillUseEvent)
            local player = skillUseEvent.from
            local target = skillUseEvent.tos[1]
            local choice1 = "head_dance_choice1"
            local choice2 = "head_dance_choice2"
            local choice3 = "head_dance_choice_both:" .. player.id
            local choices = { choice1, choice2 }
            if player:getMark("head_dance_mutation") ~= 0 then
                table.insertIfNeed(choices, choice3)
            end
            local valid = table.clone(choices)
            if target:isKongcheng() then
                table.removeOne(valid, choice1)
                table.removeOne(valid, choice3)
            end
            HY.ReplaceHandCardToTemp(target, player:getCardIds("h"))
            local result = room:askToChoice(target, {
                choices = valid,
                skill_name = head_dance.name,
                all_choices = choices,
                cancelable = false,
            })
            HY.ReverseHandCardFromTemp(target)
            if result == choice1 then
                HY.ReplaceHandCardToTempNew(player, target:getCardIds("h"))
                local cards = HY.AskForCard(player, 1, 1, false, head_dance.name, false, nil, "head_dance_prompt_throw::" .. target.id, nil, true)
                HY.ReverseHandCardFromTempNew(player)
                room:throwCard(cards, head_dance.name, target, player)
                room:loseHp(target, 1, head_dance.name)
            elseif result == choice2 then
                local marks = target:getTableMark("@@head_dance")
                table.insertIfNeed(marks, player.id)
                room:setPlayerMark(target, "@@head_dance", marks)
            else
                room:loseHp(player, 1, head_dance.name)
                if not player.dead then
                    HY.ReplaceHandCardToTempNew(player, target:getCardIds("h"))
                    local cards = HY.AskForCard(player, 1, 1, false, head_dance.name, false, nil, "head_dance_prompt_throw::" .. target.id, nil, true)
                    HY.ReverseHandCardFromTempNew(player)
                    room:throwCard(cards, head_dance.name, target, player)
                    room:loseHp(target, 1, head_dance.name)
                    local marks = target:getTableMark("@@head_dance")
                    table.insertIfNeed(marks, player.id)
                    room:setPlayerMark(target, "@@head_dance", marks)
                end
            end
        end
    })
    head_dance:addEffect(fk.AfterCardsMove, {
        can_trigger = function(self, event, target, player, data)
            for _, move in ipairs(data) do
                if move.to and not move.to.dead and move.to ~= player and move.moveReason == fk.ReasonDraw then
                    local marks = move.to:getTableMark("@@head_dance")
                    return player:hasSkill(head_dance.name) and table.contains(marks, player.id) and #move.to:getCardIds("h") >= #player:getCardIds("h")
                end
            end
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local count = #player:getCardIds("h")
            for _, move in ipairs(data) do
                if move.to and not move.to.dead and move.to ~= player and move.moveReason == fk.ReasonDraw then
                    local marks = move.to:getTableMark("@@head_dance")
                    local min_discard = #move.to:getCardIds("h") - count + 1
                    if table.contains(marks, player.id) and min_discard > 0 then
                        room:askToDiscard(move.to, {
                            min_num = min_discard,
                            max_num = 999,
                            skill_name = head_dance.name,
                            cancelable = false,
                        })
                    end
                end
            end
        end,
    })
    head_dance:addEffect(fk.TurnStart, {
        can_refresh = function(self, event, target, player, data)
            return target == player and table.filter(player.room:getAlivePlayers(), function(t)
                return table.contains(t:getTableMark("@@head_dance"), player.id)
            end)
        end,
        on_refresh = function(self, event, target, player, data)
            local room = player.room
            for _, t in ipairs(room:getAlivePlayers()) do
                local marks = t:getTableMark("@@head_dance")
                table.removeOne(marks, player.id)
                if #marks == 0 then
                    room:setPlayerMark(t, "@@head_dance", 0)
                else
                    room:setPlayerMark(t, "@@head_dance", marks)
                end
            end
        end
    })
    head_dance:addLoseEffect(function(self, player, is_death)
        local room = player.room
        for _, t in ipairs(room:getAlivePlayers()) do
            local marks = t:getTableMark("@@head_dance")
            table.removeOne(marks, player.id)
            if #marks == 0 then
                room:setPlayerMark(t, "@@head_dance", 0)
            else
                room:setPlayerMark(t, "@@head_dance", marks)
            end
        end
    end)
    local infinity_eyes = fk.CreateSkill {
        name = "infinity_eyes",
    }
    infinity_eyes:addEffect(fk.AfterCardsMove, {
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(infinity_eyes.name) and not player.dead and player:isKongcheng() and
                table.any(player.room:getOtherPlayers(player), function(t)
                    return not t:isKongcheng()
                end) and table.any(data, function(move)
                    return move.from and move.from == player and table.any(move.moveInfo, function(info)
                        return info.fromArea == Card.PlayerHand
                    end)
                end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            local targets = room:askToChoosePlayers(player, {
                targets = table.filter(room:getOtherPlayers(player), function(t)
                    return not t:isKongcheng()
                end),
                min_num = 1,
                max_num = 1,
                skill_name = infinity_eyes.name,
                prompt = "infinity_eyes_prompt"
            })
            if #targets == 1 then
                event:setCostData(self, targets[1])
                return true
            end
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local cards = room:askToCards(event:getCostData(self), {
                min_num = 1,
                max_num = 1,
                skill_name = infinity_eyes.name,
                prompt = "infinity_eyes_prompt_give",
                cancelable = false
            })
            if type(cards) == "number" then
                cards = { cards }
            end
            room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, infinity_eyes.name, nil, false, player)
            room:drawCards(event:getCostData(self), 1, infinity_eyes.name)
        end
    })
    extension:loadSkillSkels { head_dance, infinity_eyes }
    hy_sekibanki:addSkills { "head_dance", "infinity_eyes" }
    Fk:loadTranslationTable {
        ["hy_sekibanki"] = "赤蛮奇",
        ["#hy_sekibanki"] = "俯视众生之首",
        ["designer:hy_sekibanki"] = "黑曜人形",
        ["illustrator:hy_sekibanki"] = "ザコザコY",
        ["cv:hy_sekibanki"] = "",

        ["head_dance"] = "舞首",
        [":head_dance"] = "<a href='genetics_skill'>遗传技</a>，出牌阶段限一次，你可以令一名其他角色观看你的手牌，然后其须选择一项：1.令你观看其手牌并弃置其中一张，然后其失去1点体力；2.直到你的下回合开始，其摸牌后须将手牌弃置至小于你。突变：其可以背水并令你失去1点体力。",
        [":head_dance_mutation"] = "<a href='genetics_skill'>遗传技</a>，出牌阶段限一次，你可以令一名其他角色观看你的手牌，然后其须选择一项：1.令你观看其手牌并弃置其中一张，然后其失去1点体力；2.直到你的下回合开始，其摸牌后须将手牌弃置至小于你。<font color='red'>突变</font>：其可以背水并令你失去1点体力。",
        ["head_dance_prompt"] = "舞首：你可以令一名其他角色观看你的手牌",
        ["head_dance_prompt_throw"] = "舞首：弃置%dest一张手牌并令%dest失去1点体力",
        ["head_dance_choice1"] = "被观看手牌弃牌并失去体力",
        ["head_dance_choice2"] = "被限制摸牌后手牌数",
        ["head_dance_choice_both"] = "背水：%src失去1点体力",
        ["@@head_dance"] = "舞首",

        ["infinity_eyes"] = "续目",
        [":infinity_eyes"] = "在你失去所有手牌后，你可以令一名角色交给你一张手牌并摸一张牌。",
        ["infinity_eyes_prompt"] = "续目：你可以令一名角色交给你一张手牌",
        ["infinity_eyes_prompt_give"] = "续目：你须交出一张手牌"
    }
end
